package com.lcz.manage.util;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import org.springframework.util.CollectionUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * @author lucz@yunrong.cn
 * @version V3.0
 * @date 2021/9/24 15:01
 */
@Slf4j
public class AsyncUtils {

    /**
     * 【非阻塞】
     * 异步线程调用模板代码
     *
     * @param runnable
     * @return void
     */
    public static void runAsync(Runnable runnable) {
        CompletableFuture.runAsync(runnable);
    }

    /**
     * 【阻塞】
     * 异步线程调用模板代码
     *
     * @param executorPool
     * @param suppliers
     * @return void
     */
    public static <T> List<Future<Object>> waitAsync(ExecutorService executorPool, List<T> suppliers,
        Consumer<T> asyncAction) {
        if (CollectionUtils.isEmpty(suppliers)) {
            return Collections.emptyList();
        }
        List<Callable<Object>> collect = suppliers.stream()
            .map(m -> (Callable<Object>) () -> {
                Thread currentThread = Thread.currentThread();
                String oriThreadName = currentThread.getName();
                try {
                    asyncAction.accept(m);
                    return new Object();
                } finally {
                    currentThread.setName(oriThreadName);
                }
            })
            .collect(Collectors.toList());
        try {
            return executorPool.invokeAll(collect);
        } catch (InterruptedException e) {
            log.error("线程池异步执行任务失败", e);
            Thread.currentThread()
                .interrupt();
        }
        return Collections.emptyList();
    }

}
